#!/usr/bin/python
import sys, json, urllib2, re, nmap

#This script seeks out a pinglable global IP address part of the superprefix of a given subprefix

#Iterate through async namp scan results immediately breaking when an ICMP host-up has been sought.
#------------------------------------------------------------------------------------------------------------------------------------------------------------------------
def scanCallback(host, scan_result):
    if int(scan_result.get("nmap").get("scanstats").get("uphosts")) == 1:
        sys.exit(str(scan_result.get("nmap").get("command_line")).rsplit(' ')[5])
#------------------------------------------------------------------------------------------------------------------------------------------------------------------------


#Get prefix as argv input and clean trailing slashes in case of subnet mask specification
subprefix = sys.argv[1]
if "/" in subprefix:
    subprefix = re.sub("/","%2F",subprefix)

#Get super-prefix via RIPEStat Address Space Hierarchy widget
#------------------------------------------------------------------------------------------------------------------------------------------------------------------------
jsondata = urllib2.urlopen("https://stat.ripe.net/data/address-space-hierarchy/data.json?aggr_levels_below=7&get_org_names=true&resource="+str(subprefix)).read()
#Convert json to python
(true,false,null) = (True,False,None)
result = eval(jsondata)
if "-" in result.get("data").get("exact")[0].get("inetnum"):
    superprefix = result.get("data").get("less_specific")[0].get("inetnum")
else:
    superprefix = result.get("data").get("exact")[0].get("inetnum")
#------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#Execute an NMAP scan, which looks for ICMP reachable hosts in target superprefix. ATLAS probes do 
#both ICMP and traditional UDP destination unreachable ( @ UDP ports 33434..(x+100)) traceroutes, 
#however this script only seeks out ICMP reachable ones.
#------------------------------------------------------------------------------------------------------------------------------------------------------------------------
print superprefix
nm = nmap.PortScannerAsync()
nm.scan(hosts=superprefix, arguments='-sn -T5', callback=scanCallback)
while nm.still_scanning():
   nm.wait(1)
#------------------------------------------------------------------------------------------------------------------------------------------------------------------------



